package top.lingkang.ciyuanwaf.utils.terminal;

import cn.hutool.core.thread.ThreadUtil;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author lingkang
 * Created by 2023/11/25
 */
public class TerminalUtils {
    private static final Map<String, String> map = new HashMap<>();
    private static final ReentrantLock lock = new ReentrantLock();

    public static void cdNginxDir(TerminalThread thread, String path) {
        if (OsUtils.isWindow()) {
            if (path.toLowerCase().startsWith("c")) {
                thread.send("cd " + path);
            } else {
                thread.send(path.substring(0, 1) + ":");
                thread.send("cd " + path);
            }
        } else {
            thread.send("cd " + path);
            thread.send("pwd");
        }
    }

    public static boolean nginxIsRun(TerminalThread thread) {
        lock.lock();
        String method = "nginxIsRun";
        String tag = "nginxIsRun_";
        map.put(method, "false");
        TerminalEvent event = new TerminalEvent() {
            @Override
            public void receive(String str) {
                if (str.contains(tag) || str.contains("nginx.exe")
                        || str.contains("master process")) {
                    map.put(tag, "true");
                    if (str.contains("nginx.exe") || str.contains("master process")) {
                        map.put(method, "true");
                    }
                }
            }
        };
        thread.addEvent(event);
        if (OsUtils.isWindow())
            thread.send("tasklist | findstr nginx && echo nginxIsRun_");
        else {
            thread.send("pwd");
            thread.send("ps -ef | grep nginx && echo nginxIsRun_");
        }
        for (int i = 0; ; i++) {
            if (map.containsKey(tag) || i > 3) {
                map.remove(tag);
                break;
            }
            ThreadUtil.sleep(500);
        }
        thread.removeEvent(event);
        lock.unlock();
        return "true".equals(map.get(method));
    }

    /**
     * nginx: the configuration file ./conf/nginx.conf syntax is ok
     * nginx: configuration file ./conf/nginx.conf test is successful
     * nginxCheck
     */
    public static String nginxCheck(TerminalThread thread) {
        lock.lock();
        String method = "nginxCheck";
        String tag = "nginxCheck_";
        map.put(method, "");
        TerminalEvent event = new TerminalEvent() {
            @Override
            public void receive(String str) {
                if (str.contains(tag) && !str.contains("echo " + tag)) {
                    map.put(tag, "true");
                    map.put(method, str);
                }
            }
        };
        thread.addEvent(event);
        if (OsUtils.isWindow()) {
            thread.send("nginx -t && echo nginxCheck_");
        } else {
            thread.send("pwd");
            thread.send("./nginx -t && echo nginxCheck_");
        }
        for (int i = 0; ; i++) {
            if (map.containsKey(tag) || i > 3) {
                map.remove(tag);
                break;
            }
            ThreadUtil.sleep(500);
        }
        lock.unlock();
        thread.removeEvent(event);
        return map.get(method);
    }

    /**
     * stopNginx_
     */
    public static String stopNginx(TerminalThread thread) {
        lock.lock();
        String method = "stopNginx";
        String tag = "stopNginx_";

        map.put(method, "");
        TerminalEvent event = new TerminalEvent() {
            @Override
            public void receive(String str) {
                if (str.contains(tag)) {
                    map.put(tag, "true");
                    map.put(method, str);
                }
            }
        };
        thread.addEvent(event);
        if (OsUtils.isWindow()) {
            thread.send("taskkill /F /IM nginx.exe && ping 127.0.0.1 -n 3 >nul && echo stopNginx_");
        } else {
            thread.send("pwd");
            thread.send("kill -9 $(pgrep -f nginx) && sleep 1 && echo stopNginx_");
        }

        for (int i = 0; ; i++) {
            if (map.containsKey(tag) || i > 6) {
                map.remove(tag);
                break;
            }
            ThreadUtil.sleep(500);
        }
        thread.removeEvent(event);
        lock.unlock();
        return map.get(method);
    }

    /**
     * startNginx_
     */
    public static String startNginx(TerminalThread thread) {
        lock.lock();
        String method = "startNginx";
        String tag = "startNginx_";

        map.put(method, "");
        TerminalEvent event = new TerminalEvent() {
            @Override
            public void receive(String str) {
                if (str.contains(tag)) {
                    map.put(tag, "true");
                    map.put(method, str);
                }
            }
        };
        thread.addEvent(event);
        if (OsUtils.isWindow()) {
            thread.send("start nginx && ping 127.0.0.1 -n 3 >nul && echo startNginx_");
        } else {
            thread.send("pwd");
            thread.send("./nginx && sleep 1 && echo startNginx_");
        }

        int i = 0;
        for (; ; i++) {
            if (map.containsKey(tag) || i > 6) {
                map.remove(tag);
                break;
            }
            ThreadUtil.sleep(500);
        }
        thread.removeEvent(event);
        lock.unlock();
        return map.get(method);
    }

}
